home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / SpriteWorld 2.0 ƒ / SpriteWorld Examples / Tiling Demo / Tiling Demo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-12  |  13.3 KB  |  512 lines  |  [TEXT/KAHL]

  1. ///--------------------------------------------------------------------------------------
  2. // Tiling Demo.c
  3. //
  4. // By Vern Jensen, August 1995
  5. ///--------------------------------------------------------------------------------------
  6.  
  7.  
  8. #include <SWIncludes.h>
  9. #include <SWGameUtils.h>
  10. #include <SWDitherDown.h>
  11. #include <SWFPSReport.h>
  12.  
  13. #include "SWApplication.h"
  14. #include "Tiling Demo.h"
  15.  
  16.  
  17. #define    kFullScreenWindow            true        // Makes the window fill the screen
  18. #define    kInterlacedMode                false        // Turns Interlaced mode on/off
  19. #define kSyncToVBL                    false        // Syncs animation to VBL
  20. #define kWorldRectInset                0            // Makes SpriteWorld smaller than window
  21. #define kMaxFPS                        30            // Set to 0 for unrestricted speed
  22.  
  23. #define kNumDiamonds                10            // Number of diamonds
  24. #define kMaxDiamondMoveDelta        5            // Max speed for the diamonds
  25.  
  26. #define kTileWidth                    40            // Don't change these unless you
  27. #define kTileHeight                    40            // change the resource as well.
  28.  
  29.  
  30. enum tileIDs            // Meaningful values for the tileIDs
  31. {
  32.     kWallTile,
  33.     kBoardTile,
  34.     kMaxNumTiles
  35. };
  36.  
  37.  
  38.  
  39. /***********/
  40. /* Globals */
  41. /***********/
  42.  
  43. SpriteWorldPtr    gSpriteWorldP;
  44.  
  45. SpriteLayerPtr    gTopDiamondSpriteLayerP;
  46. SpriteLayerPtr    gBottomDiamondSpriteLayerP;
  47.     
  48. TileMapPtr        gTileMap;
  49. SpritePtr        gBallSpriteP;
  50. WindowPtr        gWindowP;
  51.  
  52. DrawProcPtr        gSpriteDrawProc;
  53. short            gNumTileMapRows, gNumTileMapCols;
  54.  
  55.  
  56. ///--------------------------------------------------------------------------------------
  57. // Main
  58. ///--------------------------------------------------------------------------------------
  59.  
  60. void    main( void )
  61. {
  62.     Initialize(kNumberOfMoreMastersCalls);
  63.     
  64.     if (SWHasSystem7())
  65.     {
  66.         SetCursor(*GetCursor(watchCursor));
  67.         
  68.         CreateSpriteWorld();
  69.         SetUpTiling();
  70.         CreateSprites();
  71.         
  72.         SetCursor(&qd.arrow);
  73.         HideCursor();
  74.         
  75.         SetUpAnimation();
  76.         RunAnimation();
  77.         ShutDown();
  78.     }
  79.     else
  80.     {
  81.         CantRunOnThisMachine();
  82.     }
  83. }
  84.  
  85.  
  86. ///--------------------------------------------------------------------------------------
  87. // CreateSpriteWorld
  88. ///--------------------------------------------------------------------------------------
  89.  
  90. void    CreateSpriteWorld( void )
  91. {
  92.     Rect        offscreenRect, worldRect, windRect;
  93.     RgnHandle    mBarUpdateRgn;
  94.     OSErr        err;
  95.     
  96.     gWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
  97.     
  98.     if (gWindowP != NULL)
  99.     {
  100.         if (kFullScreenWindow == true)
  101.         {
  102.             SizeWindow(gWindowP, qd.screenBits.bounds.right, 
  103.                     qd.screenBits.bounds.bottom, false);
  104.             MoveWindow(gWindowP, 0, 0, false);
  105.         }
  106.         else
  107.         {
  108.                 // Center window in screen
  109.             windRect = gWindowP->portRect;
  110.             CenterRect(&windRect, &qd.screenBits.bounds);
  111.             MoveWindow(gWindowP, windRect.left, windRect.top, false);
  112.         }
  113.         
  114.         ShowWindow(gWindowP);
  115.         SetPort(gWindowP);
  116.         mBarUpdateRgn = HideMenuBar(gWindowP); // Must be done *after* showing window!
  117.         EraseRgn(mBarUpdateRgn);
  118.         
  119.         if (kInterlacedMode)
  120.             PaintRect(&gWindowP->portRect);    // Blacken window for Interlaced mode
  121.     }
  122.     else
  123.         CantFindResource();
  124.     
  125.     
  126.     err = SWEnterSpriteWorld();
  127.     FatalError(err);
  128.  
  129.     
  130.     worldRect = gWindowP->portRect; 
  131.     InsetRect(&worldRect, kWorldRectInset, kWorldRectInset);
  132.     
  133.     
  134.         // Set size of offscreen area
  135.     offscreenRect = worldRect;
  136.     OffsetRect(&offscreenRect, -offscreenRect.left, -offscreenRect.top);
  137.     
  138.  
  139.         // Make offscreen area evenly divisible by tile width & height
  140.     if ( (offscreenRect.right/kTileWidth)*kTileWidth != offscreenRect.right)
  141.         offscreenRect.right = (offscreenRect.right/kTileWidth)*kTileWidth + kTileWidth;
  142.     
  143.     if ( (offscreenRect.bottom/kTileHeight)*kTileHeight != offscreenRect.bottom)
  144.         offscreenRect.bottom = (offscreenRect.bottom/kTileHeight)*kTileHeight + kTileHeight;
  145.     
  146.     
  147.     gNumTileMapRows = offscreenRect.bottom / kTileHeight;
  148.     gNumTileMapCols = offscreenRect.right / kTileWidth;
  149.     
  150.  
  151.     err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP, 
  152.             &worldRect, &offscreenRect);
  153.     FatalError(err);
  154.     
  155.     
  156.     if (gSpriteWorldP->pixelDepth == 8)            // 256 colors
  157.     {
  158.         gSpriteDrawProc = CompiledSprite8BitDrawProc;
  159.     }
  160.     else                                        // not 256 colors
  161.     {
  162. #if !SW_PPC
  163.         if (kInterlacedMode)
  164.             gSpriteDrawProc = BPAllBitInterlacedMaskDrawProc;
  165.         else
  166.             gSpriteDrawProc = BlitPixieAllBitMaskDrawProc;
  167. #else
  168.         gSpriteDrawProc = SWStdSpriteDrawProc;
  169. #endif
  170.     }
  171. }
  172.  
  173.  
  174. ///--------------------------------------------------------------------------------------
  175. // SetUpTiling
  176. ///--------------------------------------------------------------------------------------
  177.  
  178. void    SetUpTiling( void )
  179. {
  180.     short        row, col;
  181.     OSErr        err;
  182.     
  183.     
  184.         // Must be done before we can load the tiles.
  185.     err = SWInitTiling(gSpriteWorldP, kTileHeight, kTileWidth, kMaxNumTiles);
  186.     FatalError(err);
  187.     
  188.     err = SWCreateTileMap(gSpriteWorldP, &gTileMap, gNumTileMapRows, gNumTileMapCols);
  189.     FatalError(err);
  190.  
  191.     
  192.     // For demonstration purposes, we've decided to load the tiles from CICN
  193.     // resources here, and load them from PICT resources in the Scrolling Demo.
  194.     
  195.         // Load the wall tile
  196.     SWLoadTileFromCicnResource(
  197.         gSpriteWorldP, 
  198.         kWallTile,            // tileID
  199.         200,                 // CICN resource ID
  200.         kFatMask);            // maskType
  201.     
  202.         // Load the board ("wire") tile
  203.     SWLoadTileFromCicnResource(
  204.         gSpriteWorldP, 
  205.         kBoardTile,            // tileID
  206.         201,                 // CICN resource ID
  207.         kFatMask);            // maskType
  208.  
  209.     
  210.         // Initialize the values in the tileMap
  211.     for (row = 0; row < gNumTileMapRows; row++)
  212.     {
  213.         for (col = 0; col < gNumTileMapCols; col++)
  214.         {
  215.             if (row == 0 || col == 0 || row == gNumTileMapRows-1 || col == gNumTileMapCols-1)
  216.                 gTileMap[row][col] = kWallTile;
  217.             else
  218.                 gTileMap[row][col] = kBoardTile;
  219.         }
  220.     }
  221. }
  222.  
  223.  
  224. ///--------------------------------------------------------------------------------------
  225. // CreateSprites
  226. ///--------------------------------------------------------------------------------------
  227.  
  228. void    CreateSprites( void )
  229. {
  230.     SpritePtr            diamondSpriteP;
  231.     SpritePtr            tempSpriteP;
  232.     short                spriteNum;
  233.     Point                moveDelta, mousePoint;
  234.     Rect                moveBounds;
  235.     OSErr                err;
  236.     
  237.     
  238.         // Create the sprite layers
  239.     SWCreateSpriteLayer(&gTopDiamondSpriteLayerP);
  240.     SWCreateSpriteLayer(&gBottomDiamondSpriteLayerP);
  241.     FatalError(SWStickyError());
  242.     
  243.     
  244.     moveBounds = gSpriteWorldP->backRect;
  245.     InsetRect(&moveBounds, 40, 40);
  246.     
  247.         // create and set up the diamond sprites
  248.     for (spriteNum = 0; spriteNum < kNumDiamonds; spriteNum++)
  249.     {
  250.         if (spriteNum == 0)
  251.         {
  252.             err = SWCreateSpriteFromPictResource(gSpriteWorldP,
  253.                 &diamondSpriteP, 
  254.                 NULL,        // pointer to memory for sprite
  255.                 128,         // picture resource id
  256.                 128,         // mask resource id (we use self-masking)
  257.                 1,             // max frames
  258.                 kFatMask);    // mask type
  259.             FatalError(err);
  260.             SWCompileSprite(diamondSpriteP);
  261.             tempSpriteP = diamondSpriteP;
  262.         }
  263.         else
  264.         {
  265.             err = SWCloneSprite(diamondSpriteP, &tempSpriteP, NULL);
  266.             FatalError(err);
  267.         }
  268.         
  269.  
  270.         SWSetSpriteMoveBounds(tempSpriteP, &moveBounds);
  271.         SWSetSpriteMoveProc(tempSpriteP, DiamondSpriteMoveProc);
  272.         SWSetSpriteFrameTime(tempSpriteP, 2000);
  273.         
  274.         SWSetSpriteLocation(tempSpriteP, 
  275.                 GetRandom(40, gSpriteWorldP->backRect.right-80), 
  276.                 GetRandom(40, gSpriteWorldP->backRect.bottom-80));
  277.         
  278.         do
  279.         {
  280.             moveDelta.h = GetRandom(-kMaxDiamondMoveDelta, kMaxDiamondMoveDelta);
  281.             moveDelta.v = GetRandom(-kMaxDiamondMoveDelta, kMaxDiamondMoveDelta);
  282.         } while (!moveDelta.v || !moveDelta.h);
  283.         
  284.         SWSetSpriteMoveDelta(tempSpriteP, moveDelta.h, moveDelta.v);
  285.         SWSetSpriteDrawProc(tempSpriteP, gSpriteDrawProc);
  286.         SWAddSprite(gTopDiamondSpriteLayerP, tempSpriteP);
  287.     }
  288.     
  289.     
  290.         // Create the ball sprite
  291.     err = SWCreateSpriteFromCicnResource(gSpriteWorldP, &gBallSpriteP, NULL, 
  292.             128, 1, kFatMask);    
  293.     FatalError(err);
  294.     SWCompileSprite(gBallSpriteP);
  295.     
  296.     
  297.         // Set up the ball sprite
  298.     SWAddSprite(gTopDiamondSpriteLayerP, gBallSpriteP);
  299.     SWSetSpriteMoveProc(gBallSpriteP, MouseSpriteMoveProc);
  300.     SWSetSpriteDrawProc(gBallSpriteP, gSpriteDrawProc);
  301.     GetMouse(&mousePoint);
  302.     SWSetSpriteLocation(gBallSpriteP, mousePoint.h - 20, mousePoint.v - 20);
  303.     
  304.     SWAddSpriteLayer(gSpriteWorldP, gBottomDiamondSpriteLayerP);    // Add bottom first, so it is drawn first
  305.     SWAddSpriteLayer(gSpriteWorldP, gTopDiamondSpriteLayerP);        // Add top last, so it is drawn last
  306.  
  307.     SWLockSpriteWorld(gSpriteWorldP);
  308.     
  309.     
  310.         // Test out the dithering routines in DitherDown.c. 
  311.         // See DitherDown.c for more info.
  312.     if (gSpriteWorldP->pixelDepth < 8)
  313.     {
  314.             // Dither the diamond sprite
  315.         DitherDownPict(128, diamondSpriteP->frameArray[0]->framePort);
  316.         LowerMaskDepth(128, diamondSpriteP->frameArray[0]->maskPort);
  317.         
  318.             // Dither the wall tile
  319.         DitherDownCicn(200, gSpriteWorldP->tileFrameArray[kWallTile]->framePort);
  320.     }
  321. }
  322.  
  323.  
  324. ///--------------------------------------------------------------------------------------
  325. // SetUpAnimation
  326. ///--------------------------------------------------------------------------------------
  327.  
  328. void    SetUpAnimation( void )
  329. {
  330.     SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
  331.     SWSyncSpriteWorldToVBL(gSpriteWorldP, kSyncToVBL);
  332.     
  333.  
  334.     if (gSpriteWorldP->pixelDepth !=8)
  335.     {
  336. #if !SW_PPC
  337.         if (kInterlacedMode)
  338.         {
  339.             SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BPAllBitInterlacedRectDrawProc);
  340.             SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BPAllBitInterlacedRectDrawProc);
  341.             SWSetTileMaskDrawProc(gSpriteWorldP, BPAllBitInterlacedPartialMaskDrawProc);
  342.         }
  343.         else
  344.         {
  345.             SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  346.             SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  347.             SWSetTileMaskDrawProc(gSpriteWorldP, BlitPixieAllBitPartialMaskDrawProc);
  348.         }
  349. #endif
  350.     }
  351.     else    // 256 colors
  352.     {
  353.         if (kInterlacedMode)
  354.         {
  355.             SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BP8BitInterlacedRectDrawProc);
  356.             SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BP8BitInterlacedRectDrawProc);
  357.             SWSetTileMaskDrawProc(gSpriteWorldP, BP8BitInterlacedPartialMaskDrawProc);
  358.         }
  359.         else
  360.         {
  361.             SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
  362.             SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
  363.             SWSetTileMaskDrawProc(gSpriteWorldP, BlitPixie8BitPartialMaskDrawProc);
  364.         }
  365.     }
  366.     
  367.     ForeColor(blackColor);
  368.     BackColor(whiteColor);
  369.     
  370.  
  371.     SWDrawTilesInBackground(gSpriteWorldP);
  372.     SWUpdateSpriteWorld(gSpriteWorldP, true);
  373. }
  374.  
  375.  
  376. ///--------------------------------------------------------------------------------------
  377. //  RunAnimation
  378. ///--------------------------------------------------------------------------------------
  379.  
  380.     
  381. void    RunAnimation( void )
  382. {
  383.     unsigned long        frames;
  384.     
  385.     frames = 0;
  386.     StartTimer();
  387.     
  388.     
  389.     while (!Button())
  390.     {
  391.         SWProcessSpriteWorld(gSpriteWorldP);
  392.         SWAnimateSpriteWorld(gSpriteWorldP);
  393.         
  394.         if (gSpriteWorldP->frameHasOccured)
  395.             frames++;
  396.     }
  397.     
  398.     ShowMenuBar(gWindowP);
  399.     ShowResults(frames);
  400. }
  401.  
  402.  
  403. ///--------------------------------------------------------------------------------------
  404. //  ShutDown (clean up and dispose of the SpriteWorld)
  405. ///--------------------------------------------------------------------------------------
  406.  
  407.  
  408. void    ShutDown( void )
  409. {
  410.     SWUnlockSpriteWorld(gSpriteWorldP);
  411.     SWDisposeSpriteWorld(gSpriteWorldP);
  412.     SWExitSpriteWorld();
  413.     
  414.     FlushEvents(everyEvent, 0);
  415.     ShowCursor();
  416. }
  417.  
  418.  
  419. ///--------------------------------------------------------------------------------------
  420. //  MouseSpriteMoveProc
  421. ///--------------------------------------------------------------------------------------
  422.  
  423.  
  424. void MouseSpriteMoveProc(SpritePtr srcSpriteP)
  425. {
  426.     Point                mousePoint;
  427.     SpritePtr            tempSpriteP;
  428.     EventRecord            event;
  429.     short                theChar;
  430.     
  431.     
  432.         // Move the ball sprite
  433.     GetMouse(&mousePoint);
  434.     SWMoveSprite(srcSpriteP, mousePoint.h - 20, mousePoint.v - 20);
  435.     
  436.     
  437.         // Change ball sprite layers if the spacebar was hit
  438.     while ( GetOSEvent(keyDownMask, &event) )
  439.     {
  440.         theChar = (event.message & charCodeMask);
  441.         
  442.         if (theChar == ' ')
  443.         {
  444.             if (srcSpriteP->isUnderTiles)
  445.             {
  446.                 SWSetSpriteUnderTiles(srcSpriteP, false);
  447.                 SWRemoveSprite(gBottomDiamondSpriteLayerP, srcSpriteP);
  448.                 SWAddSprite(gTopDiamondSpriteLayerP, srcSpriteP);
  449.             }
  450.             else
  451.             {
  452.                 SWSetSpriteUnderTiles(srcSpriteP, true);
  453.                 SWRemoveSprite(gTopDiamondSpriteLayerP, srcSpriteP);
  454.                 SWAddSprite(gBottomDiamondSpriteLayerP, srcSpriteP);
  455.             }
  456.         }
  457.     }
  458.     
  459.         
  460.         // Check for collision with diamonds in same layer as ball //
  461.  
  462.     if (srcSpriteP->isUnderTiles)
  463.         tempSpriteP = gBottomDiamondSpriteLayerP->headSpriteP;
  464.     else
  465.         tempSpriteP = gTopDiamondSpriteLayerP->headSpriteP;
  466.     
  467.  
  468.     while (tempSpriteP != NULL)
  469.     {
  470.             // are the sprite’s rectangles overlapping?
  471.         if (tempSpriteP != gBallSpriteP &&
  472.             (tempSpriteP->destFrameRect.top < gBallSpriteP->destFrameRect.bottom) &&
  473.             (tempSpriteP->destFrameRect.bottom > gBallSpriteP->destFrameRect.top) &&
  474.             (tempSpriteP->destFrameRect.left < gBallSpriteP->destFrameRect.right) &&
  475.             (tempSpriteP->destFrameRect.right > gBallSpriteP->destFrameRect.left))
  476.         {
  477.                 // Check to see if the masks overlap
  478.             if ( SWRegionCollision(tempSpriteP, gBallSpriteP)) 
  479.             {
  480.                     // Switch diamond position above/under tiles
  481.                 if (tempSpriteP->isUnderTiles)
  482.                 {
  483.                     SWSetSpriteUnderTiles(tempSpriteP, false);
  484.                     SWRemoveSprite(gBottomDiamondSpriteLayerP, tempSpriteP);
  485.                     SWAddSprite(gTopDiamondSpriteLayerP, tempSpriteP);
  486.                 }
  487.                 else
  488.                 {
  489.                     SWSetSpriteUnderTiles(tempSpriteP, true);
  490.                     SWRemoveSprite(gTopDiamondSpriteLayerP, tempSpriteP);
  491.                     SWAddSprite(gBottomDiamondSpriteLayerP, tempSpriteP);
  492.                 }
  493.             }
  494.         }
  495.         
  496.         tempSpriteP = tempSpriteP->nextSpriteP;
  497.     }
  498. }
  499.  
  500.  
  501. ///--------------------------------------------------------------------------------------
  502. //  DiamondSpriteMoveProc
  503. ///--------------------------------------------------------------------------------------
  504.  
  505.  
  506. void    DiamondSpriteMoveProc(SpritePtr ballSpriteP)
  507. {    
  508.     SWOffsetSprite(ballSpriteP, ballSpriteP->horizMoveDelta, ballSpriteP->vertMoveDelta);
  509.     SWBounceSprite(ballSpriteP);
  510. }
  511.  
  512.